/** 
 * @author Riccardo Manfrin [namesurname at gmail dot com]
 * 
 * @brief  Packet data generation and management for transmission
 * 
 */
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h> /* gettimeofday */
#include <arpa/inet.h> /* htonl */
#include <string.h>
#include "rdata.h"
#include "wifi.h"

enum {
	DATA_NOT_INITIALIZED,
	BUFFER_OVERUN
} err_code;

typedef struct{
	char enable;
	int  seqn;
} rdata_seq;

static char *data = NULL;

static rdata_seq rdataseq;
static char wlanchan=0;


static int gen_type = 0;

static void error(int e);

static void error(int e)
{
	printf("rdata.c : ERR_CODE %i\n",(int)e);
	return;
}

void rdata_init(int stat_dyn){
	
	rdataseq.enable=0;
	rdataseq.seqn=0;
	
	if(data==NULL)
	{
		data=malloc(MAX_LENGTH);
		if(stat_dyn==STATIC)
		{
			int i = 0;
			for (i=0; i<MAX_LENGTH; i++)
			{
				//Not "real random data" but it's fair enough
				data[i] = i%256;
			}
			gen_type=STATIC;
		}
		else
		{
			gen_type=DYNAMIC;
		}
	}
	return;
}

void rdata_free(){
	free(data);
	return;
}

/**
 * General purpose access method to 
 * change parameters and value relative
 * to the features implemented in rdata.
 */
void rdata_set(int param, int value){
	switch(param){
		case( SEQUENCE ): 
		{
			if(!rdataseq.enable)
			{
				rdataseq.enable=1;
				rdataseq.seqn=0;
			}
			break;
		}
		case( WLANCHAN ):
		{
		  if(wifi_getEn()==WIFIENABLED)
		  {
		    wlanchan=1;
		  }
		}
		default: {break;}
	}
	return;
}

unsigned char *rdata_gen(unsigned int sz)
{
	unsigned int size = sz;
	if(gen_type==DYNAMIC)
	{
	  if(size>MAX_LENGTH)
	  {
	    error(BUFFER_OVERUN);
	    size=MAX_LENGTH;
	  }
	  if(data!=NULL)
	  {
	    int iters;
	    int left;
	    int rnd;
	    struct timeval tv;
	    gettimeofday(&tv, NULL);
	    srand((int)tv.tv_usec);
	    iters = size/sizeof(int);
	    left = size%sizeof(int);
	    while(iters)
	    {
		    rnd=rand();
		    memcpy(data+iters*sizeof(int)-(sizeof(int)-left),&rnd,sizeof(int));
		    iters--;
	    }
	    rnd=rand();
	    memcpy(data,&rnd,sizeof(int));
	  }
	  else
	  {
	    error(DATA_NOT_INITIALIZED);
	    return NULL;
	  }
	}
	else if(gen_type==STATIC)
	{
	  if(size>MAX_LENGTH) error(BUFFER_OVERUN);
	}
	
	if(rdataseq.enable)
	{
	  int tmp = htonl(rdataseq.seqn);
	  memcpy((int*) data, &tmp, sizeof(int));
	  rdataseq.seqn++;
	}
	if(wlanchan)
	{
	  int tmp = wifi_getCh();
	  memcpy((int*) (data+sizeof(int)), &tmp, sizeof(int));
	}
	return (unsigned char*) data;
}
